package com.liveims.webims.session;

import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;

import com.alcatel.as.session.distributed.Session;
import com.alcatel.as.session.distributed.SessionException;
import com.alcatel.as.session.distributed.SessionType;
import com.alcatel.as.session.distributed.SessionManager.AddSessionListenerCallback;
import com.alcatel.as.session.distributed.event.AttributeEvent;
import com.alcatel.as.session.distributed.event.SessionEvent;
import com.alcatel.as.session.distributed.event.SessionEventFilter;
import com.alcatel.as.session.distributed.event.SessionListener;
import com.liveims.webims.util.WimsMessage;

public class IMSAdapter implements SessionListener, AddSessionListenerCallback {
	
	private static Logger log = Logger.getLogger(IMSAdapter.class);
		
	protected LinkedList<IMListener> IMls;
	protected LinkedList<PresenceListener> Pls;
	protected String sid;
	
	public IMSAdapter (String sid){
		this.sid = sid;
		IMls = new LinkedList<IMListener>();
		Pls = new LinkedList<PresenceListener>();
	}
    
	/**
	 * This method should be called when the listeners are added
	 * @throws SessionException 
	 */
	public void activate() throws SessionException{
		 IMSManager.getInstance().addListener(this, sid, this);
	}
	
	public void handleEvent(List events) {
       // First get the 2-tuple session identifier/session type that uniquely identifies the session on which
       // we are notified. Since all events in the list will return the same tuple, we use the first event.
       SessionEvent e = (SessionEvent) events.get(0);
       log.debug("get notified by the session");
       for (int i = 0; i < events.size(); i++) {
	         e = (SessionEvent) events.get(0);
	         Session.Attribute attr;
	         switch (e.getEventType()) {
	         case SessionEventFilter.EVENT_ATTRIBUTE_ADDED:
	           log.info("Receiving attribute added event");
	           //get the new attribute;
	           attr = ((AttributeEvent) e).getAttribute();
               if (attr.getName() == IMSManager.IM_ATTRIBUTE){
            	   WimsMessage m = (WimsMessage)attr.getValue();
            	   this.notifyIMListeners(m);
               }else if (attr.getName() == IMSManager.Presence_ATTRIBUTE){
            	   WimsMessage m = (WimsMessage)attr.getValue();
            	   this.notifyPresenceListeners(m);
               }
	           break;
	         case SessionEventFilter.EVENT_ATTRIBUTE_UPDATED:
	        	 log.info("Receiving attribute update event");
		           //get the new attribute;
		           attr = ((AttributeEvent) e).getAttribute();
	               if (attr.getName() == IMSManager.IM_ATTRIBUTE){
	            	   WimsMessage m = (WimsMessage)attr.getValue();
	            	   this.notifyIMListeners(m);
	               }else if (attr.getName() == IMSManager.Presence_ATTRIBUTE){
	            	   WimsMessage m = (WimsMessage)attr.getValue();
	            	   this.notifyPresenceListeners(m);
	               }
	           break;

	         }
	    }
	}
	
	public void addIMListener(IMListener l){
		IMls.add(l);		
	}
	
	public void addPresenceListener(PresenceListener l){
		Pls.add(l);		
	}
	
	public void removeIMListener (IMListener l){
	    IMls.remove(l);
	}

	public void removePresenceListener (PresenceListener l){
	    Pls.remove(l);
	}
	
	private void notifyIMListeners(WimsMessage m) {
		for (int i = 0; i < IMls.size(); i++){
             IMls.get(i).IMReceived(m);
		}	
	}
	
	private void notifyPresenceListeners(WimsMessage m){
		for (int i = 0; i < Pls.size(); i++){
            Pls.get(i).NotifyReceived(m);
		}	
	}

	public void addSessionListenerCompleted(SessionType type, String sessionId,
			SessionListener listener, int listenerId) {
		log.debug("Successfully added listener on distributed session \""
				+ IMSManager.SESSION_ADMIN_TYPE + "\"");
         log.debug("Waiting for \""+IMSManager.IM_ATTRIBUTE + "&" +IMSManager.Presence_ATTRIBUTE+ "\" attribute events");		
	}

	public void addSessionListenerFailed(SessionType type, String sessionId,
			SessionListener listener, SessionException error) {
		log.error("Failed to add listener on distributed session", error);
		
	}
}
